var $ = require("jquery");
$window = $(window);
/**
    $("a.lazy").lazyload({
        lazydata: true, //indicates if it is lazyload for data,if false lazyload image.
        threshold: 10,
        lazydataParams: {
            url: "http://" + window.location.host + "/Ashx/LazyLoadData.ashx",
            params:{ itemid: "data|itemid",appid:"attr|appid" }, //it will be attached to $(this)($(this).data("itemid"),$(this).attr("appid")) for lazyload obejct.
            dataType: 'json',// $.ajax dataType
            callback: function (data, settings)
            {
                $(this).html("[" + data.ReviewCount + "ÈËÆÀÂÛ]");
                console.log(data.ReviewCount, ".......success");
            }
        } 
    });
    */

/* Convenience methods in jQuery namespace.           */
/* Use as  $.belowthefold(element, {threshold : 100, container : window}) */

$.belowthefold = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.height() + $window.scrollTop();
    } else {
        fold = $container.offset().top + $container.height();
    }

    return fold <= $(element).offset().top - settings.threshold;
};

$.rightoffold = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.width() + $window.scrollLeft();
    } else {
        fold = $container.offset().left + $container.width();
    }

    return fold <= $(element).offset().left - settings.threshold;
};

$.abovethetop = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.scrollTop();
    } else {
        fold = $container.offset().top;
    }

    return fold >= $(element).offset().top + settings.threshold + $(element).height();
};

$.leftofbegin = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.scrollLeft();
    } else {
        fold = $container.offset().left;
    }

    return fold >= $(element).offset().left + settings.threshold + $(element).width();
};

$.inviewport = function(element, settings) {
    return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
};

/* Custom selectors for your convenience.   */
/* Use as $("img:below-the-fold").something() */

$.extend($.expr[':'], {
    "below-the-fold": function(a) {
        return $.belowthefold(a, {
            threshold: 0,
            container: window
        });
    },
    "above-the-top": function(a) {
        return !$.belowthefold(a, {
            threshold: 0,
            container: window
        });
    },
    "right-of-screen": function(a) {
        return $.rightoffold(a, {
            threshold: 0,
            container: window
        });
    },
    "left-of-screen": function(a) {
        return !$.rightoffold(a, {
            threshold: 0,
            container: window
        });
    },
    "in-viewport": function(a) {
        return !$.inviewport(a, {
            threshold: 0,
            container: window
        });
    },
    /* Maintain BC for couple of versions. */
    "above-the-fold": function(a) {
        return !$.belowthefold(a, {
            threshold: 0,
            container: window
        });
    },
    "right-of-fold": function(a) {
        return $.rightoffold(a, {
            threshold: 0,
            container: window
        });
    },
    "left-of-fold": function(a) {
        return !$.rightoffold(a, {
            threshold: 0,
            container: window
        });
    }
});
$.fn.lazyload = function(options) {
    var elements = this;
    var settings = {
        threshold: 0,
        failure_limit: 0,
        event: "scroll",
        effect: "show",
        container: window,
        data_attribute: "original",
        skip_invisible: true,
        appear: null,
        load: null,
        lazydata: false, //indicates if it is lazyload for data,if false lazyload image.
        lazydataParams: {
            url: null, //ajax url
            params: {}, // ajax params object {}
            dataType: 'json', // $.ajax dataType
            callback: function() {} // it is a function while lazyloading for data,($self, data, settings) $self is Jquery object.
        }
    };

    function update() {
        var counter = 0;

        elements.each(function() {
            var $this = $(this);
            if (settings.skip_invisible && !$this.is(":visible")) {
                return;
            }
            if ($.abovethetop(this, settings) ||
                $.leftofbegin(this, settings)) {
                /* Nothing. */
            } else if (!$.belowthefold(this, settings) && !$.rightoffold(this, settings)) {
                $this.trigger("appear");
            } else {
                if (++counter > settings.failure_limit) {
                    return false;
                }
            }
        });
    }

    if (options) {
        /* Maintain BC for a couple of versions. */
        if (undefined !== options.failurelimit) {
            options.failure_limit = options.failurelimit;
            delete options.failurelimit;
        }
        if (undefined !== options.effectspeed) {
            options.effect_speed = options.effectspeed;
            delete options.effectspeed;
        }

        $.extend(settings, options);
    }

    /* Cache container as jQuery as object. */
    $container = (settings.container === undefined ||
        settings.container === window) ? $window : $(settings.container);

    /* Fire one scroll event per scroll. Not one scroll event per image. */
    if (0 === settings.event.indexOf("scroll")) {
        $container.bind(settings.event, function(event) {
            return update();
        });
    }

    this.each(function() {
        var self = this;
        var $self = $(self);

        self.loaded = false;

        /* When appear is triggered load original image. */
        $self.one("appear", function() {
            if (!this.loaded) {
                if (settings.appear) {
                    var elements_left = elements.length;
                    settings.appear.call(self, elements_left, settings);
                }
                if (!settings.lazydata) {
                    $("<img />")
                        .bind("load", function() {
                            $self
                                .hide()
                                .attr("src", $self.data(settings.data_attribute))[settings.effect](settings.effect_speed);
                            self.loaded = true;

                            /* Remove image from array so it is not looped next time. */
                            var temp = $.grep(elements, function(element) {
                                return !element.loaded;
                            });
                            elements = $(temp);

                            if (settings.load) {
                                var elements_left = elements.length;
                                settings.load.call(self, elements_left, settings);
                            }
                        })
                        .attr("src", $self.data(settings.data_attribute));
                } else {
                    var _lzyparam = {};
                    for (var i in settings.lazydataParams.params) {
                        var curParamValue = settings.lazydataParams.params[i].split("|");
                        switch (curParamValue[0].toLowerCase()) {
                            case "data":
                                _lzyparam[i] = $self.data(curParamValue[1]);
                                break;
                            case "attr":
                                _lzyparam[i] = $self.attr(curParamValue[1]);
                                break;
                            case "prop":
                                _lzyparam[i] = $self.prop(curParamValue[1]);
                                break;
                            default:
                                _lzyparam[i] = curParamValue[0];
                        }
                    }
                    $.ajax({
                        type: "POST",
                        url: settings.lazydataParams.url,
                        data: _lzyparam,
                        dataType: settings.lazydataParams.dataType,
                        success: function(data) {
                            self.loaded = true;
                            /* Remove image from array so it is not looped next time. */
                            var temp = $.grep(elements, function(element) {
                                return !element.loaded;
                            });
                            elements = $(temp);
                            if (settings.lazydataParams.callback) {
                                settings.lazydataParams.callback.call(self, data, settings);
                            }
                        }
                    });
                }
            }
        });

        /* When wanted event is triggered load original image */
        /* by triggering appear.                              */
        if (0 !== settings.event.indexOf("scroll")) {
            $self.bind(settings.event, function(event) {
                if (!self.loaded) {
                    $self.trigger("appear");
                }
            });
        }
    });

    /* Check if something appears when window is resized. */
    $window.bind("resize", function(event) {
        update();
    });

    /* Force initial check if images should appear. */
    update();

    return this;
};

exports.lazyload = function(selector, options) {
    $(selector).lazyload(options);
};
